import os
import random
import pandas as pd
from openpyxl import load_workbook
from loguru import logger
import shutil

# 全局变量定义
# 室分共建共享核查文件路径
CHECK_EXCEL_PATH = '/Users/ricochen/program/base_station/test/template/室分共建共享核查.xlsx'
# 室分共址新建会审结果确认表文件路径
CONFIRM_EXCEL_PATH = '/Users/ricochen/program/base_station/test/template/室分共址新建会审结果确认表(分批).xlsx'
# 移动自建室分工作表名称
MOBILE_SELF_BUILD_SHEET = '移动自建室分'
# 处理结果工作表名称
RESULT_SHEET = '处理结果'
# 模板工作表名称
TEMPLATE_SHEET = '模板'
# 数据开始写入行号
START_ROW = 17
# 最大处理组数
MAX_GROUPS = 3
# 每组数据行数范围
MIN_GROUP_SIZE = 13
MAX_GROUP_SIZE = 16

@logger.catch
def process_room_sharing_excel()->pd.DataFrame:
    """
    处理室分共建共享核查Excel文件
    1. 读取template目录下的"室分共建共享核查.xlsx"文件
    2. 读取"移动自建室分"sheet
    3. 过滤出电信、联通或铁塔共址站点名称非空的数据
    4. 新建"同址单位"列，根据条件添加相应的单位名称
    5. 将数据写回Excel文件
    """
    # 检查文件是否存在
    if not os.path.exists(CHECK_EXCEL_PATH):
        logger.error(f"文件未找到: {CHECK_EXCEL_PATH}")
        return None
    
    # 读取Excel文件中的特定sheet
    df = pd.read_excel(CHECK_EXCEL_PATH, sheet_name=MOBILE_SELF_BUILD_SHEET, dtype={'共建共享申请编号': str})
    
    # 确保必要的列存在
    required_columns = ['移动站点名称', '电信共址站点名称', '联通共址站点名称', '铁塔共址站点名称']
    for col in required_columns:
        if col not in df.columns:
            logger.error(f"Excel文件中未找到列: {col}")
            return None
    
    # 过滤数据：电信、联通或铁塔共址站点名称非空
    filtered_df = df[df['电信共址站点名称'].notna() | df['联通共址站点名称'].notna() | df['铁塔共址站点名称'].notna()].copy()
    
    # 新建"同址单位"列
    filtered_df['同址单位'] = ''
    
    # 根据条件填充"同址单位"列
    for index, row in filtered_df.iterrows():
        units = []
        if pd.notna(row['电信共址站点名称']):
            units.append('东莞电信分公司')
        if pd.notna(row['联通共址站点名称']):
            units.append('东莞联通分公司')
        if pd.notna(row['铁塔共址站点名称']):
            units.append('东莞铁塔分公司')
        
        # 使用分号分隔多个单位
        filtered_df.at[index, '同址单位'] = ';'.join(units)
    
    # 写回Excel文件 - 修正后的代码
    # 先加载工作簿
    book = load_workbook(CHECK_EXCEL_PATH)
    
    # 检查是否存在"处理结果"sheet，如果存在则删除
    if RESULT_SHEET in book.sheetnames:
        del book[RESULT_SHEET]
    # 直接在原DataFrame上修改（inplace=True）
    filtered_df.rename(columns={'C': 'new_C'}, inplace=True)

    logger.success(f"共处理了{len(filtered_df)}条数据。")
    
    return filtered_df

#把dataframe写入
@logger.catch
def write_xls(df:pd.DataFrame,excel_path:str):
    # 创建ExcelWriter对象并关联已加载的工作簿
    with pd.ExcelWriter(excel_path, engine='openpyxl', mode='a') as writer:
        # 将处理后的数据写入新的sheet
        df.to_excel(writer, sheet_name=RESULT_SHEET, index=False)
    
    logger.info(f"处理完成！已将结果写入'{excel_path}'的'{RESULT_SHEET}'sheet中。")
    logger.info(f"共处理了{len(df)}条数据。")
        

def copy_template_sheet(new_sheet_name:str='1', target_file_path:str=None):
    """
    复制室分共址新建会审结果确认表中的模板工作表
    1. 读取template目录下的"室分共址新建会审结果确认表(分批)_电信.xlsx"文件
    2. 复制"模板"sheet，保持原格式
    3. 新sheet命名为"1"
    4. 插入到工作簿最后
    5. 重新保存文件
    
    参数:
        new_sheet_name: 新工作表的名称
        target_file_path: 目标文件路径，如果为None则使用CONFIRM_EXCEL_PATH
    """
    # 如果未指定目标文件路径，则使用全局变量
    file_path = target_file_path if target_file_path else CONFIRM_EXCEL_PATH
    
    # 检查文件是否存在
    if not os.path.exists(file_path):
        logger.error(f"文件未找到: {file_path}")
        return False
    
    try:
        # 加载工作簿
        book = load_workbook(file_path)
        
        # 检查是否存在模板sheet
        if TEMPLATE_SHEET not in book.sheetnames:
            logger.error(f"文件中未找到'{TEMPLATE_SHEET}'工作表")
            return False
        
        # 获取模板sheet
        template_sheet = book[TEMPLATE_SHEET]
        
        # 如果已存在名为'1'的sheet，先删除
        if new_sheet_name in book.sheetnames:
            logger.info(f"工作表'{new_sheet_name}'已存在，将被替换")
            del book[new_sheet_name]
        
        # 创建新的工作表并复制模板内容和格式
        new_sheet = book.copy_worksheet(template_sheet)
        new_sheet.title = new_sheet_name
        
        # 将新工作表移动到工作簿最后
        book.move_sheet(new_sheet, offset=len(book.sheetnames) - 1)
        
        # 保存工作簿
        book.save(file_path)
        
        logger.info(f"成功复制'{TEMPLATE_SHEET}'工作表为'{new_sheet_name}'并保存到'{file_path}'")
        return True
    except Exception as e:
        logger.error(f"复制工作表时发生错误: {str(e)}")
        return False

@logger.catch
def write_data_by_groups(df: pd.DataFrame):
    """
    根据DataFrame记录数，按10-16的随机数分组，每组新建一个sheet并写入数据
    
    参数:
        df: 包含处理数据的DataFrame
    """
    # 检查原始文件是否存在
    if not os.path.exists(CONFIRM_EXCEL_PATH):
        logger.error(f"文件未找到: {CONFIRM_EXCEL_PATH}")
        return False
    
    try:
        # 生成复制后的文件路径
        # 获取文件名和扩展名
        file_dir = os.path.dirname(CONFIRM_EXCEL_PATH)
        file_name = os.path.basename(CONFIRM_EXCEL_PATH)
        name_without_ext, ext = os.path.splitext(file_name)
        
        # 构建新文件名：原文件名后加"-"+MOBILE_SELF_BUILD_SHEET
        new_file_name = f"{name_without_ext}-{MOBILE_SELF_BUILD_SHEET}{ext}"
        new_file_path = os.path.join(file_dir, new_file_name)
        
        # 复制文件
        shutil.copy2(CONFIRM_EXCEL_PATH, new_file_path)
        logger.info(f"成功复制文件到: {new_file_path}")
        
        # 获取数据总行数
        total_rows = len(df)
        if total_rows == 0:
            logger.warning("没有数据需要处理")
            return True
        
        logger.info(f"开始处理{total_rows}条数据，按{MIN_GROUP_SIZE}-{MAX_GROUP_SIZE}的随机数分组...")
        
        # 初始化当前行索引
        current_index = 0
        group_number = 1
        
        while current_index < total_rows:
            # 生成指定范围内的随机数作为每组的行数
            group_size = random.randint(MIN_GROUP_SIZE, MAX_GROUP_SIZE)
            # 确保不超过总记录数
            end_index = min(current_index + group_size, total_rows)
            
            # 提取当前组的数据
            group_data = df.iloc[current_index:end_index]
            
            # 复制模板工作表，新表名为当前组号
            sheet_name = str(group_number)
            logger.info(f"正在处理第{group_number}组，从第{current_index}条到{end_index}的数据，包含{len(group_data)}条数据...")
            
            # 调用copy_template_sheet函数复制模板，指定目标文件路径
            if not copy_template_sheet(sheet_name, new_file_path):
                logger.error(f"复制模板工作表{sheet_name}失败")
                current_index = end_index
                group_number += 1
                continue
            
            # 加载工作簿并获取新建的工作表
            book = load_workbook(new_file_path)
            sheet = book[sheet_name]
            
            # 写入数据到工作表
            b5_text = f"根据通建办共建共享管理要求以及本地运营商共建工作开展需要，2025年同址新建室分站点需通建办联合移动、电信、联通三家运营商进行同地点新建协调审核，确认无法共建共享才可新建。本次会审{len(group_data)}个站点，详见下方清单，前期已将单站点设计方案发给各运营商接口人审核。"
            sheet[f'B5'] = b5_text
            for row_idx, (_, data_row) in enumerate(group_data.iterrows(), start=START_ROW):
                # A列: 共建共享申请编号
                sheet[f'A{row_idx}'] = data_row.get('共建共享申请编号', '')
                # B列: 移动站点名称
                sheet[f'B{row_idx}'] = data_row.get('移动站点名称', '')
                # C列: 东莞电信分公司
                sheet[f'C{row_idx}'] = '东莞移动分公司'
                # D列: 同址单位
                sheet[f'D{row_idx}'] = data_row.get('同址单位', '')
                # E列: 室分覆盖方案不满足友商覆盖需求
                sheet[f'E{row_idx}'] = '室分覆盖方案不满足友商覆盖需求'
            
            # 保存工作簿到复制的文件
            book.save(new_file_path)
            logger.info(f"成功将第{group_number}组数据写入工作表'{sheet_name}'")
            
            # 更新索引和组号
            current_index = end_index
            group_number += 1
        
        logger.success(f"所有数据处理完成！共创建了{group_number - 1}个工作表，结果保存在: {new_file_path}")
        return True
    except Exception as e:
        logger.error(f"按组写入数据时发生错误: {str(e)}")
        return False

if __name__ == "__main__":
    # 先处理室分共建共享数据
    logger.info("\n开始处理室分共建共享核查Excel文件...")
    df = process_room_sharing_excel()
    
    # 如果数据处理成功且有数据，则按组写入
    if df is not None and not df.empty:
        logger.info("\n开始按组写入数据到室分共址新建会审结果确认表...")
        write_data_by_groups(df)
    else:
        logger.warning("没有处理到数据或数据为空，跳过按组写入步骤")
